#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_gfxPrimitives.h"
#include <string>
#include <sstream>
#include <iostream>
#include "MyTimer.h"
#include <math.h>
#include <vector>

#define SCREEN_WIDTH						1040
#define SCREEN_HEIGHT						740
#define SCREEN_BPP							32

#define AVATAR_WIDTH						20
#define AVATAR_HEIGHT						20

#define FRAMES_PER_SECOND					20

#define MUL8_UP								0
#define MUL8_DOWN							1
#define MUL8_RIGHT							2
#define MUL8_LEFT							3
#define MUL8_UP_LEFT						4
#define MUL8_DOWN_RIGHT						5
#define MUL8_UP_RIGHT						6
#define MUL8_DOWN_LEFT						7

#define VELOCITY							3

#define HALF_FIELD_VERTICALLY				370
#define	HALF_FIELD_HORIZONTALLY				520

#define FIELD_POSITION_1					0
#define FIELD_POSITION_2					1
#define FIELD_POSITION_3					2
#define FIELD_POSITION_4					3
#define FIELD_POSITION_5					4
#define FIELD_POSITION_6					5
#define FIELD_POSITION_7					6
#define FIELD_POSITION_8					7
#define FIELD_POSITION_9					8
#define FIELD_POSITION_10					9
#define FIELD_POSITION_11					10
#define FIELD_POSITION_12					11
#define FIELD_POSITION_13					12
#define FIELD_POSITION_14					13
#define FIELD_POSITION_15					14

#define WAYPOINT_UPPER_LEFT					1
#define WAYPOINT_UPPER_RIGHT				2
#define WAYPOINT_LOWER_LEFT					3
#define WAYPOINT_LOWER_RIGHT				4

#define PI 3.14159265

// Define surfaces
SDL_Surface* screen = NULL;
SDL_Surface* background = NULL;
SDL_Surface* message = NULL;

TTF_Font* font = NULL;
SDL_Color textColor = {255, 255, 255};
SDL_Event event;
MyTimer fps;

// Rectangle for MU-L8 images
SDL_Rect mul8[8];

SDL_Rect fieldpos[14];

class Ball {
protected:
	SDL_Rect position;
	int radius;
	int xVel;
	int yVel;
	SDL_Surface* sprite;
public:
	Ball();
	virtual ~Ball();
	void show();
	std::vector<SDL_Rect> getBall();
	SDL_Rect getPosition();
	SDL_Rect getCenter();
	int getLocation();
};

class StationaryBall : public Ball {
public:
	void handle_input(SDL_Rect);
	void move(SDL_Rect);
	void move();
};

class MoveableBall : public Ball {
public:
	MoveableBall();
	virtual ~MoveableBall();
	void move();
	void handle_input();
};

class Avatar {
private:
	SDL_Rect position;
	int currentDirection;
	int xVel, yVel;
	SDL_Surface* avatar;
	std::vector<SDL_Rect> waypoints;
public:
	Avatar();
	virtual ~Avatar();
	void move();
	void autonomousMove(SDL_Rect);
	void autonomousMove(SDL_Rect, std::vector<SDL_Rect>);
	void autonomousMove(Ball&, int);
	void handle_input();
	void show();
	SDL_Rect getPosition();
	SDL_Rect getCenter();
	void setWaypoint(std::pair<int,int>);
	void showWaypoints(bool);
	int getDirectionTowards(SDL_Rect);
	int getDistanceTo(SDL_Rect);
};

double toRadians(int degrees) {
	return degrees * PI / 180.0;
}

int toDegrees(double radians) {
	return radians * 180 / PI;
}

bool init() {
	if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
		return false;
	}

	// Set up the screen
	screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
			SDL_SWSURFACE |/* SDL_FULLSCREEN |*/ SDL_DOUBLEBUF);

	// If there was an error in setting up the screen
	if (screen == NULL) {
		return false;
	}

	if (TTF_Init() == -1) {
		return false;
	}

	// Set the window caption
	SDL_WM_SetCaption("SiMU-L8 Soccer Demo", NULL);

	mul8[0].x = 0;
	mul8[0].y = 0;
	mul8[0].w = 20;
	mul8[0].h = 20;

	mul8[2].x = 0;
	mul8[2].y = 26;
	mul8[2].w = 20;
	mul8[2].h = 19;

	mul8[1].x = 0;
	mul8[1].y = 51;
	mul8[1].w = 20;
	mul8[1].h = 19;

	mul8[3].x = 0;
	mul8[3].y = 76;
	mul8[3].w = 20;
	mul8[3].h = 19;

	mul8[4].x = 0;
	mul8[4].y = 101;
	mul8[4].w = 20;
	mul8[4].h = 19;

	mul8[5].x = 0;
	mul8[5].y = 126;
	mul8[5].w = 20;
	mul8[5].h = 19;

	mul8[6].x = 0;
	mul8[6].y = 151;
	mul8[6].w = 20;
	mul8[6].h = 19;

	mul8[7].x = 0;
	mul8[7].y = 176;
	mul8[7].w = 20;
	mul8[7].h = 19;

	fieldpos[FIELD_POSITION_1].x = 70;
	fieldpos[FIELD_POSITION_1].y = 70;
	fieldpos[FIELD_POSITION_1].w = 210;
	fieldpos[FIELD_POSITION_1].h = 220-70;

	fieldpos[FIELD_POSITION_2].x = 280;
	fieldpos[FIELD_POSITION_2].y = 70;
	fieldpos[FIELD_POSITION_2].w = 520-280;
	fieldpos[FIELD_POSITION_2].h = 220-70;

	fieldpos[FIELD_POSITION_3].x = 520;
	fieldpos[FIELD_POSITION_3].y = 70;
	fieldpos[FIELD_POSITION_3].w = 760-520;
	fieldpos[FIELD_POSITION_3].h = 220-70;

	fieldpos[FIELD_POSITION_4].x = 760;
	fieldpos[FIELD_POSITION_4].y = 70;
	fieldpos[FIELD_POSITION_4].w = 210;
	fieldpos[FIELD_POSITION_4].h = 220-70;

	fieldpos[FIELD_POSITION_5].x = 70;
	fieldpos[FIELD_POSITION_5].y = 220;
	fieldpos[FIELD_POSITION_5].w = 210;
	fieldpos[FIELD_POSITION_5].h = 300;

	fieldpos[FIELD_POSITION_6].x = 280;
	fieldpos[FIELD_POSITION_6].y = 220;
	fieldpos[FIELD_POSITION_6].w = 520-280;
	fieldpos[FIELD_POSITION_6].h = 300;

	fieldpos[FIELD_POSITION_7].x = 520;
	fieldpos[FIELD_POSITION_7].y = 220;
	fieldpos[FIELD_POSITION_7].w = 760-520;
	fieldpos[FIELD_POSITION_7].h = 300;

	fieldpos[FIELD_POSITION_8].x = 760;
	fieldpos[FIELD_POSITION_8].y = 220;
	fieldpos[FIELD_POSITION_8].w = 210;
	fieldpos[FIELD_POSITION_8].h = 300;

	fieldpos[FIELD_POSITION_9].x = 70;
	fieldpos[FIELD_POSITION_9].y = 520;
	fieldpos[FIELD_POSITION_9].w = 210;
	fieldpos[FIELD_POSITION_9].h = 670-520;

	fieldpos[FIELD_POSITION_10].x = 280;
	fieldpos[FIELD_POSITION_10].y = 520;
	fieldpos[FIELD_POSITION_10].w = 520-280;
	fieldpos[FIELD_POSITION_10].h = 670-520;

	fieldpos[FIELD_POSITION_11].x = 520;
	fieldpos[FIELD_POSITION_11].y = 520;
	fieldpos[FIELD_POSITION_11].w = 760-520;
	fieldpos[FIELD_POSITION_11].h = 670-520;

	fieldpos[FIELD_POSITION_12].x = 760;
	fieldpos[FIELD_POSITION_12].y = 520;
	fieldpos[FIELD_POSITION_12].w = 210;
	fieldpos[FIELD_POSITION_12].h = 670-520;

	fieldpos[FIELD_POSITION_13].x = 10;
	fieldpos[FIELD_POSITION_13].y = 220;
	fieldpos[FIELD_POSITION_13].w = 60;
	fieldpos[FIELD_POSITION_13].h = 300;

	fieldpos[FIELD_POSITION_14].x = 970;
	fieldpos[FIELD_POSITION_14].y = 220;
	fieldpos[FIELD_POSITION_14].w = 60;
	fieldpos[FIELD_POSITION_14].h = 300;

	return true;
}

void setup() {
	SDL_Surface* tempBackground = IMG_Load("src/soccer_field_updated_5_20.bmp");

	background = SDL_DisplayFormat(tempBackground);

	SDL_FreeSurface(tempBackground);

	font = TTF_OpenFont("src/DarkistheNight.ttf", 28);

	message = TTF_RenderText_Solid(font, "Collision", textColor);
}

void close() {
	//Free the loaded image
	SDL_FreeSurface( background );

	TTF_Quit();

	//Quit SDL
	SDL_Quit();
}

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL) {
	// Make temp rectangle to hold offsets
	SDL_Rect offset;

	offset.x = x;
	offset.y = y;

	SDL_BlitSurface(source, clip, destination, &offset);
}

bool checkCollision(std::vector<SDL_Rect> a, std::vector<SDL_Rect> b) {
	int leftA, leftB, rightA, rightB, topA, topB, botA, botB;
	bool collision = false;
	for (unsigned i = 0; i < a.size(); i++) {
		leftA = a[i].x;
		rightA = a[i].x + a[i].w + 1;
		topA = a[i].y;
		botA = a[i].y + a[i].h + 1;

		for (unsigned j = 0; j < b.size(); j++) {
			leftB = b[i].x;
			rightB = b[i].x + b[i].w + 1;
			topB = b[i].y;
			botB = b[i].y + b[i].h + 1;

			//			if( ( ( botA <= topB ) || ( topA >= botB ) || ( rightA <= leftB ) || ( leftA >= rightB ) ) == false ) {
			//				//A collision is detected
			//				collision = true;
			//			}

			if (((topA <= botB && topA >= topB) || (botA <= botB && botA >= topB)) && ((leftA >= leftB && leftA <= leftB) || (rightA >= leftB && rightA <= rightB))) {
				collision = true;
			}
		}
	}

	return collision;
}

int main(int argc, char **argv) {

	init();

	// Create Avatar
	Avatar myAvatar;

	// Create Ball
	MoveableBall myBall;
	StationaryBall stationaryBall;

	setup();

	apply_surface(0, 0, background, screen);
	myBall.show();
	stationaryBall.show();

	if (SDL_Flip(screen) == -1) {
		return 1;
	}

	SDL_Rect myBallPosition = myBall.getPosition();
	bool quit = false;
	bool autonomous = false;

	while (!quit) {
		fps.start();
		while(SDL_PollEvent(&event)) {
			if (event.type == SDL_KEYDOWN) {
				if (event.key.keysym.sym == SDLK_q) {
					quit = true;
				}
				else if (event.key.keysym.sym == SDLK_RETURN) {
					autonomous = !(autonomous);
				}
			}
			// Check to see if user Xed out window
			else if (event.type == SDL_QUIT) {
				quit = true;
			}
		}

		if (autonomous) {
			myAvatar.autonomousMove((Ball&) stationaryBall, stationaryBall.getLocation());
		}
		else {
			myAvatar.handle_input();
			myAvatar.move();
		}
		apply_surface(0, 0, background, screen);

		myAvatar.show();

		myAvatar.showWaypoints(autonomous);

		//		myBall.handle_input();
		//		myBall.move();
		//		myBall.show();
		//		if (follow) {
		//			stationaryBall.move(myBall.getPosition());
		//		}
		stationaryBall.handle_input(myAvatar.getPosition());
		stationaryBall.move();
		stationaryBall.show();

		//		if (checkCollision(myBall.getBall(), stationaryBall.getBall())) {
		//			apply_surface(0, 0, message, screen);
		//		}

		myBallPosition = myBall.getPosition();

		/*		lineRGBA(screen, 70, 370,
				myBallPosition.x + myBallPosition.w/2, myBallPosition.y + myBallPosition.h/2,
				0, 255, 255, 255);
		 */

		if (SDL_Flip(screen) == -1) {
			return 1;
		}

		if (fps.get_ticks() < 1000 / FRAMES_PER_SECOND) {
			SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks());
		}

	}

	close();

}

Avatar::Avatar() {
	// Initialize the offsets
	position.x = 0;
	position.y = 0;
	position.w = AVATAR_WIDTH;
	position.h = AVATAR_HEIGHT;

	// Initialize the velocities
	xVel = 0;
	yVel = 0;

	// Initialize the currentDirection
	currentDirection = MUL8_DOWN;

	SDL_Surface* tempAvatar = IMG_Load("src/MU-L8_standin.bmp");

	if (tempAvatar == NULL) {
		std::cout << "Could not find avatar." << std::endl;
	}
	else {
		avatar = SDL_DisplayFormat(tempAvatar);
		//		// Map the color key
		//		Uint32 colorkey = SDL_MapRGB(avatar->format, 0xFF, 0xFF, 0xFF);
		//
		//		// Set all pixels of color R 0xFF, G 0xFF, B 0xFF to be transparent
		//		SDL_SetColorKey(avatar, SDL_SRCCOLORKEY, colorkey);
	}

	SDL_FreeSurface(tempAvatar);

	waypoints.resize(0);
}

Avatar::~Avatar() {
	SDL_FreeSurface(avatar);
}

void Avatar::setWaypoint(std::pair<int, int> newPoint) {
	bool alreadyPlotted = false;
	for (unsigned i = 0; i < waypoints.size(); i++) {
		if (waypoints[i].x == newPoint.first && waypoints[i].y == newPoint.second) {
			alreadyPlotted = true;
		}
	}

	if (!alreadyPlotted) {
		waypoints.resize(waypoints.size() + 1);
		SDL_Rect temp;
		temp.x = newPoint.first;
		temp.y = newPoint.second;
		waypoints[waypoints.size() - 1] = temp;
		std::cout << "Added waypoint (" << temp.x << ", " << temp.y << ")" << std::endl;
	}
}

void Avatar::showWaypoints(bool show) {
	if (show) {
		for (unsigned i = 0; i < waypoints.size(); i++) {
			lineRGBA(screen, (int)waypoints[i].x, (int)waypoints[i].y, (int)waypoints[i].x+3, (int)waypoints[i].y-3, 0,255,255,255);
		}
	}
}

int Avatar::getDirectionTowards(SDL_Rect target) {
	SDL_Rect myCenter = this->getCenter();
	int dx = target.x - myCenter.x;
	int dy = target.y - myCenter.y;
	int degrees = toDegrees(atan(dy/dx));
	int result = -1;
	bool flipped = false;
	if (degrees < 0) {
		flipped = true;
		degrees = degrees * -1;
	}
	if (degrees < 45/2) {
		result = MUL8_RIGHT;
	}
	else if (degrees <= 45+45/2) {
		if (flipped)
			result = MUL8_DOWN_RIGHT;
		else
			result = MUL8_UP_RIGHT;
	}
	else if (degrees <= 90+45/2) {
		if (flipped)
			result = MUL8_DOWN;
		else
			result = MUL8_UP;
	}
	else if (degrees <= 135+45/2) {
		if (flipped)
			result = MUL8_DOWN_LEFT;
		else
			result = MUL8_UP_LEFT;
	}
	else
		result = MUL8_LEFT;

	return result;
}

int Avatar::getDistanceTo(SDL_Rect target) {
	SDL_Rect myCenter = this->getCenter();
	int dx = target.x - myCenter.x;
	int dy = target.y - myCenter.y;
	int result = sqrt(dx*dx + dy*dy);
	return result;
}

void Avatar::autonomousMove(SDL_Rect goal) {
	if (waypoints.size() > 0) {
		int avatarX = this->position.x;
		int waypointX = waypoints[waypoints.size() - 1].x;
		int avatarY = this->position.y;
		int waypointY = waypoints[waypoints.size() - 1].y;
		if ((avatarX >= waypointX - VELOCITY && avatarX <= waypointX + VELOCITY) && (avatarY >= waypointY - VELOCITY && avatarY <= waypointY + VELOCITY)) {
			// We are at the current waypoint
			std::cout << "Made it to waypoint (" << waypointX << ", " << waypointY << ")" << std::endl;
			waypoints.resize(waypoints.size() - 1);
			if (waypoints.size() > 0) {
				std::cout << "Next waypoint: (" << waypoints[waypoints.size() - 1].x << ", " << waypoints[waypoints.size() - 1].y << ")" << std::endl;
			}
		}
		if (waypoints.size() > 0) {
			goal = waypoints[waypoints.size() - 1];
		}
	}

	else {
		if (goal.y < HALF_FIELD_VERTICALLY) {
			// Ball is on upper half of the field
			goal.y -= goal.h;
		}
		goal.x += goal.w;

		goal.x -= this->position.w/2;
		goal.y -= this->position.h/2;
	}

	if (goal.x < position.x) {
		if (goal.y < (position.y)) {
			position.x -= VELOCITY / sqrt(2);
			position.y -= VELOCITY / sqrt(2);
			currentDirection = MUL8_UP_LEFT;
		}
		else if (goal.y > (position.y)) {
			position.x -= VELOCITY / sqrt(2);
			position.y += VELOCITY / sqrt(2);
			currentDirection = MUL8_DOWN_LEFT;
		}
		else {
			position.x -= VELOCITY;
			currentDirection = MUL8_LEFT;
		}
	}
	else if (goal.x > position.x) {
		if (goal.y < (position.y)) {
			position.x += VELOCITY / sqrt(2);
			position.y -= VELOCITY / sqrt(2);
			currentDirection = MUL8_UP_RIGHT;
		}
		else if (goal.y > (position.y)) {
			position.x += VELOCITY / sqrt(2);
			position.y += VELOCITY / sqrt(2);
			currentDirection = MUL8_DOWN_RIGHT;
		}
		else {
			position.x += VELOCITY;
			currentDirection = MUL8_RIGHT;
		}
	}
	else if (goal.y < (position.y)) {
		position.y -= VELOCITY;
		currentDirection = MUL8_UP;
	}
	else if (goal.y > (position.y)) {
		position.y += VELOCITY;
		currentDirection = MUL8_DOWN;
	}

}

void Avatar::autonomousMove(SDL_Rect goal, std::vector<SDL_Rect> obstacles) {
	for (unsigned i = 0; i < obstacles.size(); i++) {

		/*
		bool collisionCourse = false;
		int whichWaypoint = 0;
		SDL_Rect obstacleCenter;
		obstacleCenter.x = obstacles[i].x + obstacles[i].w/2;
		obstacleCenter.y = obstacles[i].y + obstacles[i].h/2;
		int obstacleDistance = getDistanceTo(obstacleCenter);
		int goalDistance = getDistanceTo(goal);
		switch (currentDirection) {
		case MUL8_UP:
			if ((position.x <= obstacles[i].x + obstacles[i].w) && (position.x + position.w >= obstacles[i].x)
					&& currentDirection == MUL8_UP) {
				collisionCourse = true;
				if ((position.x + position.w/2) >= (obstacles[i].x + obstacles[i].w/2)) {
					// Center of avatar is to the right of the center of the obstacle
					whichWaypoint = WAYPOINT_LOWER_RIGHT;
				}
				else {
					whichWaypoint = WAYPOINT_LOWER_LEFT;
				}
			}
			break;
		case MUL8_DOWN:
			if ((position.x <= obstacles[i].x + obstacles[i].w) && (position.x + position.w >= obstacles[i].x)
					&& currentDirection == MUL8_DOWN) {
				collisionCourse = true;
				if ((position.x + position.w/2) >= (obstacles[i].x + obstacles[i].w/2)) {
					// Center of avatar is to the right of the center of the obstacle
					whichWaypoint = WAYPOINT_UPPER_RIGHT;
				}
				else {
					whichWaypoint = WAYPOINT_UPPER_LEFT;
				}
			}
			break;
		case MUL8_LEFT:
			if ((position.y <= obstacles[i].y + obstacles[i].h) && (position.y + position.h >= obstacles[i].y)
					&& currentDirection == MUL8_LEFT) {
				collisionCourse = true;
				if ((position.y + position.h/2) >= (obstacles[i].y + obstacles[i].h/2)) {
					// Center of avatar is lower than the center of the obstacle
					whichWaypoint = WAYPOINT_LOWER_RIGHT;
				}
				else {
					whichWaypoint = WAYPOINT_UPPER_RIGHT;
				}
			}
			break;
		case MUL8_RIGHT:
			if ((position.y <= obstacles[i].y + obstacles[i].h) && (position.y + position.h >= obstacles[i].y)
					&& currentDirection == MUL8_RIGHT) {
				collisionCourse = true;
				if ((position.y + position.h/2) >= (obstacles[i].y + obstacles[i].h/2)) {
					// Center of avatar is lower than the center of the obstacle
					whichWaypoint = WAYPOINT_LOWER_LEFT;
				}
				else {
					whichWaypoint = WAYPOINT_UPPER_LEFT;
				}
			}
			break;
		case MUL8_UP_LEFT:
			if ((((position.x + position.w) - obstacles[i].x) >= (position.y - (obstacles[i].y + obstacles[i].h))
					&& ((position.x - (obstacles[i].x + obstacles[i].w)) <= ((position.y + position.h) - obstacles[i].y)))
					&& currentDirection == MUL8_UP_LEFT) {
				collisionCourse = true;
				if (((position.x + position.w/2) - (obstacles[i].x + obstacles[i].w/2)) >= ((position.y + position.h/2) - (obstacles[i].y + obstacles[i].h/2))) {
					// avatar is on track to hit upper left corner
					whichWaypoint = WAYPOINT_LOWER_LEFT;
				}
				else {
					whichWaypoint = WAYPOINT_UPPER_RIGHT;
				}
			}
			break;
		case MUL8_UP_RIGHT:
			if ((((obstacles[i].x + obstacles[i].w) - position.x) <= ((obstacles[i].y + obstacles[i].h) - position.y))
					&& (((obstacles[i].x - (position.x + position.w)) >= (obstacles[i].y - (position.y + position.h))))
					&& currentDirection == MUL8_UP_RIGHT) {
				collisionCourse = true;
				if (((obstacles[i].x + obstacles[i].w/2) - (position.x + position.w/2)) >= ((obstacles[i].y + obstacles[i].h/2) - (position.y + position.h/2))) {
					// avatar is on track to hit upper left corner
					whichWaypoint = WAYPOINT_UPPER_LEFT;
				}
				else {
					whichWaypoint = WAYPOINT_LOWER_RIGHT;
				}
			}
			break;
		case MUL8_DOWN_LEFT:
			if (((position.x - (obstacles[i].x + obstacles[i].w)) <= (position.y - (obstacles[i].y + obstacles[i].h)))
					&& ((((position.x + position.w) - obstacles[i].x) >= ((position.y + position.h) - obstacles[i].y)))
					&& currentDirection == MUL8_DOWN_LEFT) {
				collisionCourse = true;
				if (((position.x + position.w/2) - (obstacles[i].x + obstacles[i].w/2)) >= ((position.y + position.h/2) - (obstacles[i].y + obstacles[i].h/2))) {
					// avatar is on track to hit upper left corner
					whichWaypoint = WAYPOINT_UPPER_LEFT;
				}
				else {
					whichWaypoint = WAYPOINT_LOWER_RIGHT;
				}
			}
			break;
		case MUL8_DOWN_RIGHT:
			if (((obstacles[i].x - (position.x + position.w)) >= ((obstacles[i].y + obstacles[i].h) - position.y)
					&& (((obstacles[i].x + obstacles[i].w) - position.x) <= (obstacles[i].y - (position.y + position.h))))
					&& currentDirection == MUL8_DOWN_RIGHT) {
				collisionCourse = true;
				if (((obstacles[i].x + obstacles[i].w/2) - (position.x + position.w/2)) >= ((obstacles[i].y + obstacles[i].h/2) - (position.y + position.h/2))) {
					// avatar is on track to hit lower left corner
					whichWaypoint = WAYPOINT_LOWER_LEFT;
				}
				else {
					whichWaypoint = WAYPOINT_UPPER_RIGHT;
				}
			}
			break;
		}

		if (collisionCourse && (goalDistance > obstacleDistance)) {
			// WE GONNA DIE!!!!!!!!
			int x = 0, y = 0;
			switch (whichWaypoint) {
			case WAYPOINT_UPPER_LEFT:
				x = obstacles[i].x - obstacles[i].w/2 - position.w;
				y = obstacles[i].y - obstacles[i].h/2 - position.h;
				break;
			case WAYPOINT_UPPER_RIGHT:
				x = obstacles[i].x + obstacles[i].w*1.5 + position.w/2;
				y = obstacles[i].y - obstacles[i].h/2 - position.h;
				break;
			case WAYPOINT_LOWER_LEFT:
				x = obstacles[i].x - obstacles[i].w/2 - position.w;
				y = obstacles[i].y + obstacles[i].h*1.5 + position.h/2;
				break;
			case WAYPOINT_LOWER_RIGHT:
				x = obstacles[i].x + obstacles[i].w*1.5 + position.w/2;
				y = obstacles[i].y + obstacles[i].h*1.5 + position.h/2;
				break;
			}
			std::pair<int, int> waypoint;
			waypoint.first = x;
			waypoint.second = y;


			if ((position.x + position.w/2) < goal.x) {
				// We need a secondary waypoint to make it all the way around the obstacle
				std::pair<int, int> secondaryWaypoint;
				if ((position.y + position.h/2) > goal.y) {
					//if (whichWaypoint == WAYPOINT_LOWER_LEFT || whichWaypoint == WAYPOINT_LOWER_RIGHT) {
						secondaryWaypoint.first = obstacles[i].x + obstacles[i].w*2 + position.w;
						secondaryWaypoint.second = obstacles[i].y - obstacles[i].h/2 - position.h;
						setWaypoint(secondaryWaypoint);
					//}
				}
				else {
					//if(whichWaypoint == WAYPOINT_UPPER_LEFT || whichWaypoint == WAYPOINT_UPPER_RIGHT) {
						secondaryWaypoint.first = obstacles[i].x + obstacles[i].w*2 + position.w;
						secondaryWaypoint.second = obstacles[i].y + obstacles[i].h*1.5 + position.h/2;
						setWaypoint(secondaryWaypoint);
					//}
				}

			}

			setWaypoint(waypoint);

		}

		*/


		if ((this->position.x <= (obstacles[i].x + obstacles[i].w))
				&& ((this->position.x + this->position.w) >= obstacles[i].x )) {
			// Object is in the same "column" as us
			if ((currentDirection == MUL8_UP || currentDirection == MUL8_UP_RIGHT || currentDirection == MUL8_UP_LEFT)
					&& (goal.y < obstacles[i].y + obstacles[i].h && obstacles[i].y + obstacles[i].h < this->position.y)) {
				// We are traveling upwards, and the goal is on the other side of the obstacle
				std::cout << "We are traveling upwards, and the goal is on the other side of the obstacle" << std::endl;
				std::pair<int, int> firstWaypoint;
				std::pair<int, int> secondWaypoint;
				if (this->position.x >= obstacles[i].x + obstacles[i].w/2) {
					// We are mostly to the right of the obstacle
					std::cout << "Obstacle is to the right" << std::endl;
					firstWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					firstWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);

					secondWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					secondWaypoint.second = obstacles[i].y - obstacles[i].h/2 + this->position.h;
				}
				else {
					// We are mostly to the left of the obstacle
					std::cout << "Obstacle is to the left" << std::endl;
					firstWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					firstWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);

					secondWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					secondWaypoint.second = obstacles[i].y - obstacles[i].h/2 + this->position.h;
				}

				setWaypoint(secondWaypoint);
				setWaypoint(firstWaypoint);

			}
			else if ((currentDirection == MUL8_DOWN || currentDirection == MUL8_DOWN_RIGHT || currentDirection == MUL8_DOWN_LEFT)
					&& (goal.y > obstacles[i].y)) {
				// We are traveling downwards, and the goal is on the other side of the obstacle
				std::pair<int, int> firstWaypoint;
				std::pair<int, int> secondWaypoint;
				if (this->position.x >= obstacles[i].x + obstacles[i].w/2) {
					// We are mostly to the right of the obstacle
					firstWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					firstWaypoint.second = obstacles[i].y - obstacles[i].h/2 + this->position.h;

					secondWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					secondWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);
				}
				else {
					// We are mostly to the left of the obstacle
					firstWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					firstWaypoint.second = obstacles[i].y - obstacles[i].h/2 + this->position.h;

					secondWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					secondWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);
				}

				setWaypoint(secondWaypoint);
				setWaypoint(firstWaypoint);
			}

			//						if (currentDirection == MUL8_UP || currentDirection == MUL8_DOWN || (currentDirection >= MUL8_UP_LEFT && currentDirection <= MUL8_DOWN_LEFT)) {
			//							// Need to modify goal position
			//							if (this->position.x >= obstacles[i].x + (obstacles[i].w/2)) {
			//								// Obstacle is to avatar's leftmost side
			//								goal.x += this->position.w;
			//							}
			//							else {
			//								goal.x -= this->position.w;
			//							}
			//
			//						}
		}
		else if ((this->position.y <= (obstacles[i].y + obstacles[i].h)) && ((this->position.y + this->position.h) >= obstacles[i].y )) {
			// Obstacle is in the same "row" as us
			if ((currentDirection == MUL8_RIGHT || currentDirection == MUL8_UP_RIGHT || currentDirection == MUL8_DOWN_RIGHT)
					&& (goal.x > obstacles[i].x + obstacles[i].w/2 && obstacles[i].x > this->position.x)) {
				// We are traveling right and the goal is on the other side of the obstacle
				std::cout << "Obstacle is in the same row as us, we are traveling right in a collision path" << std::endl;
				std::pair<int, int> firstWaypoint;
				std::pair<int, int> secondWaypoint;
				if (this->position.y + this->position.h/2 >= obstacles[i].y + obstacles[i].h/2) {
					// We are mostly to the bottom of the obstacle
					std::cout << "We are at the bottom of the obstacle" << std::endl;
					firstWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					firstWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);

					secondWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					secondWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);
				}
				else {
					// We are mostly to the top of the obstacle
					std::cout << "We are at the top of the obstacle" << std::endl;
					firstWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					firstWaypoint.second = obstacles[i].y - obstacles[i].h/2 - this->position.h;

					secondWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					secondWaypoint.second = obstacles[i].y - obstacles[i].h/2 - this->position.h;
				}

				setWaypoint(secondWaypoint);
				setWaypoint(firstWaypoint);
			}

			else if ((currentDirection == MUL8_LEFT || currentDirection == MUL8_UP_LEFT || currentDirection == MUL8_DOWN_RIGHT)
					&& (goal.x < obstacles[i].x && obstacles[i].x < this->position.x)) {
				// We are traveling left and the goal is on the other side of the obstacle
				std::cout << "Obstacle is in the same row as us, we are traveling left in a collision path" << std::endl;
				std::pair<int, int> firstWaypoint;
				std::pair<int, int> secondWaypoint;
				if (this->position.y + this->position.h/2 >= obstacles[i].y + obstacles[i].h/2) {
					// We are mostly to the bottom of the obstacle
					std::cout << "We are at the bottom of the obstacle" << std::endl;
					firstWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					firstWaypoint.second = obstacles[i].y - obstacles[i].h/2 + this->position.h;

					secondWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					secondWaypoint.second = obstacles[i].y - obstacles[i].h/2 + this->position.h;
				}
				else {
					// We are mostly to the top of the obstacle
					std::cout << "We are at the top of the obstacle" << std::endl;
					firstWaypoint.first = obstacles[i].x + (obstacles[i].w * 1.5) + this->position.w*2/3;
					firstWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);

					secondWaypoint.first = obstacles[i].x - (obstacles[i].w/2) - this->position.w;
					secondWaypoint.second = obstacles[i].y + (obstacles[i].h * 1.5);
				}

				setWaypoint(secondWaypoint);
				setWaypoint(firstWaypoint);
			}

		}

	}

	autonomousMove(goal);

}

void Avatar::autonomousMove(Ball& ball, int fieldpos) {
	//std::cout << "Field position is: " << fieldpos + 1 << std::endl;
	SDL_Rect goal = ball.getCenter();
	switch (fieldpos) {
	case FIELD_POSITION_1:
		goal.y -= goal.h;
		goal.x--;
		break;
	case FIELD_POSITION_2:
		goal.x += goal.w;
		break;
	case FIELD_POSITION_3:
		goal.x += goal.w/2;
		goal.y -= goal.h/2;
		break;
	case FIELD_POSITION_4:
		goal.x += goal.w/2;
		goal.y -= goal.h/2;
		break;
	case FIELD_POSITION_5:
		goal.x += goal.w;
		break;
	case FIELD_POSITION_6:
		goal.x += goal.w;
		break;
	case FIELD_POSITION_7:
		goal.x += goal.w;
		break;
	case FIELD_POSITION_8:
		goal.x += goal.w;
		break;
	case FIELD_POSITION_9:
		goal.y += goal.h;
		goal.x--;
		break;
	case FIELD_POSITION_10:
		goal.x += goal.w;
		break;
	case FIELD_POSITION_11:
		goal.x += goal.w/2;
		goal.y += goal.h/2;
		break;
	case FIELD_POSITION_12:
		goal.x += goal.w/2;
		goal.y += goal.h/2;
		break;
	case FIELD_POSITION_13:
		goal.x = 520;
		goal.y = 370;
		break;
	default:

		break;
	}

	std::vector<SDL_Rect> obstacles;
	obstacles.resize(1);
	obstacles[0] = ball.getPosition();
	autonomousMove(goal, obstacles);
}
void Avatar::handle_input() {
	Uint8* keystates = SDL_GetKeyState(NULL);
	if (keystates[SDLK_w]) {
		if (keystates[SDLK_a]) {
			xVel = (int) ((VELOCITY / sqrt(2)) * -1);
			yVel = (int) ((VELOCITY / sqrt(2)) * -1);
			currentDirection = MUL8_UP_LEFT;
		}
		else if (keystates[SDLK_d]) {
			xVel = (int) (VELOCITY / sqrt(2));
			yVel = (int) ((VELOCITY / sqrt(2)) * -1);
			currentDirection = MUL8_UP_RIGHT;
		}
		else {
			yVel = VELOCITY * -1;
			xVel = 0;
			currentDirection = MUL8_UP;
		}
	}
	else if (keystates[SDLK_s]) {
		if (keystates[SDLK_a]) {
			xVel = (int) ((VELOCITY / sqrt(2)) * -1);
			yVel = (int) (VELOCITY / sqrt(2));
			currentDirection = MUL8_DOWN_LEFT;
		}
		else if (keystates[SDLK_d]) {
			xVel = (int) (VELOCITY / sqrt(2));
			yVel = (int) (VELOCITY / sqrt(2));
			currentDirection = MUL8_DOWN_RIGHT;
		}
		else {
			yVel = VELOCITY;
			xVel = 0;
			currentDirection = MUL8_DOWN;
		}
	}
	else if (keystates[SDLK_a]) {
		xVel = VELOCITY * -1;
		yVel = 0;
		currentDirection = MUL8_LEFT;
	}
	else if (keystates[SDLK_d]) {
		xVel = VELOCITY;
		yVel = 0;
		currentDirection = MUL8_RIGHT;
	}
	else {
		xVel = 0;
		yVel = 0;
	}
}

void Avatar::move() {
	position.x += xVel;
	if (position.x < 0) {
		position.x = 0;
	}
	else if (position.x > SCREEN_WIDTH - AVATAR_WIDTH) {
		position.x = SCREEN_WIDTH - AVATAR_WIDTH;
	}

	position.y += yVel;
	if (position.y < 0) {
		position.y = 0;
	}
	else if (position.y > SCREEN_HEIGHT - AVATAR_HEIGHT) {
		position.y = SCREEN_HEIGHT - AVATAR_HEIGHT;
	}
}

void Avatar::show() {
	apply_surface(position.x, position.y, avatar, screen, &mul8[currentDirection]);
}

SDL_Rect Avatar::getPosition() {
	return position;
}

SDL_Rect Avatar::getCenter() {
	SDL_Rect result;
	result.x = position.x + position.w/2;
	result.y = position.y + position.h/2;
	result.w = position.w/2;
	result.h = position.h/2;

	return result;
}

Ball::Ball() {
	position.x = 515;
	position.y = 365;
	xVel = 0;
	yVel = 0;
	radius = 5;
	position.w = 2*radius;
	position.h = 2*radius;
	sprite = NULL;
	SDL_Surface* tempAvatar = IMG_Load("src/ball.bmp");

	if (tempAvatar == NULL) {
		std::cout << "Could not find ball." << std::endl;
	}
	else {
		sprite = SDL_DisplayFormat(tempAvatar);
		// Map the color key
		Uint32 colorkey = SDL_MapRGB(sprite->format, 0xFF, 0xFF, 0xFF);

		// Set all pixels of color R 0xFF, G 0xFF, B 0xFF to be transparent
		SDL_SetColorKey(sprite, SDL_SRCCOLORKEY, colorkey);
	}

	SDL_FreeSurface(tempAvatar);
}

Ball::~Ball() {
	SDL_FreeSurface(sprite);
}

void Ball::show() {
	apply_surface(position.x, position.y, sprite, screen);
}

std::vector<SDL_Rect> Ball::getBall() {
	std::vector<SDL_Rect> result;
	result.resize(5);
	result[0].x = position.x + 2;
	result[0].y = position.y;
	result[0].w = 6;
	result[0].h = 1;

	result[1].x = position.x + 1;
	result[1].y = position.y + 1;
	result[1].w = 8;
	result[1].h = 1;

	result[2].x = position.x;
	result[2].y = position.y + 2;
	result[2].w = 10;
	result[2].h = 6;

	result[3].x = position.x + 1;
	result[3].y = position.y + 8;
	result[3].w = 8;
	result[3].h = 1;

	result[4].x = position.x + 2;
	result[4].y = position.y + 9;
	result[4].w = 6;
	result[4].h = 1;

	return result;
}

SDL_Rect Ball::getPosition() {
	return position;
}

SDL_Rect Ball::getCenter() {
	SDL_Rect result;
	result.x = position.x + position.w/2;
	result.y = position.y + position.h/2;
	result.w = position.w/2;
	result.h = position.h/2;

	return result;
}

/*
 * @override the default constructor
 */
MoveableBall::MoveableBall() {
	position.x = 515;
	position.y = 365;
	xVel = 0;
	yVel = 0;
	radius = 5;
	position.w = 2*radius;
	position.h = 2*radius;
	sprite = NULL;
	SDL_Surface* tempAvatar = IMG_Load("src/avatar.bmp");

	if (tempAvatar == NULL) {
		std::cout << "Could not find ball." << std::endl;
	}
	else {
		sprite = SDL_DisplayFormat(tempAvatar);
		// Map the color key
		Uint32 colorkey = SDL_MapRGB(sprite->format, 0xFF, 0xFF, 0xFF);

		// Set all pixels of color R 0xFF, G 0xFF, B 0xFF to be transparent
		SDL_SetColorKey(sprite, SDL_SRCCOLORKEY, colorkey);
	}

	SDL_FreeSurface(tempAvatar);
}

MoveableBall::~MoveableBall() {
	SDL_FreeSurface(sprite);
}

void MoveableBall::move() {
	position.x += (xVel * 1.5);
	if (position.x < 0) {
		position.x = 0;
	}
	else if (position.x > SCREEN_WIDTH - 2*radius) {
		position.x = SCREEN_WIDTH - 2*radius;
	}

	position.y += (yVel * 1.5);
	if (position.y < 0) {
		position.y = 0;
	}
	else if (position.y > SCREEN_HEIGHT - 2*radius) {
		position.y = SCREEN_HEIGHT - 2*radius;
	}
}

void MoveableBall::handle_input() {
	Uint8* keystates = SDL_GetKeyState(NULL);
	if (keystates[SDLK_UP]) {
		yVel = VELOCITY * -1;
	}
	else if (keystates[SDLK_DOWN]) {
		yVel = VELOCITY;
	}
	else {
		yVel = 0;
	}

	if (keystates[SDLK_LEFT]) {
		xVel = VELOCITY * -1;
	}
	else if (keystates[SDLK_RIGHT]) {
		xVel = VELOCITY;
	}
	else {
		xVel = 0;
	}

}

void StationaryBall::move(SDL_Rect goal) {
	if (goal.x < position.x) {
		if (goal.y < position.y) {
			position.x -= 1;
			position.y -= 1;
		}
		else if (goal.y > position.y) {
			position.x -= 1;
			position.y += 1;
		}
		else {
			position.x -= 2;
		}
	}
	else if (goal.x > position.x) {
		if (goal.y < position.y) {
			position.x += 1;
			position.y -= 1;
		}
		else if (goal.y > position.y) {
			position.x += 1;
			position.y += 1;
		}
		else {
			position.x += 2;
		}
	}
	else if (goal.y < position.y) {
		position.y -= 2;
	}
	else if (goal.y > position.y) {
		position.y += 2;
	}
}

void StationaryBall::handle_input(SDL_Rect other) {
	SDL_Rect myPosition = this->getPosition();
	xVel = 0;
	yVel = 0;

	int otherTop, otherBot, otherLeft, otherRight;
	int ballTop, ballBot, ballLeft, ballRight, ballWidth, ballHeight;

	otherTop = other.y; otherLeft = other.x;
	otherBot = otherTop + other.h; otherRight = otherLeft + other.w;

	ballTop = myPosition.y; ballLeft = myPosition.x;
	ballBot = ballTop + myPosition.h; ballRight = ballLeft + myPosition.w;
	ballWidth = myPosition.w; ballHeight = myPosition.h;

	if ((otherRight <= ballLeft + ballWidth/2) && (otherRight >= ballLeft)) {
		// Object is pushing from the left
		//std::cout << "Pushing from the left" << std::endl;
		if ((otherBot <= ballTop + (ballHeight * 1/4)) && (otherBot >= ballTop)) {
			// -60 degree push
			xVel = VELOCITY * cos(toRadians(-60));
			yVel = VELOCITY * sin(toRadians(60));
		}
		else if ((otherBot <= ballTop + (ballHeight * 1/2)) && (otherBot >= ballTop + (ballHeight * 1/4))) {
			// -45 degree push
			xVel = VELOCITY * cos(toRadians(-45));
			yVel = VELOCITY * sin(toRadians(45));
		}
		else if ((otherBot <= ballTop + (ballHeight * 3/4)) && (otherBot >= ballTop + (ballHeight * 1/2))) {
			// -30 degree push
			xVel = VELOCITY * cos(toRadians(-30));
			yVel = VELOCITY * sin(toRadians(30));
		}
		else if ((otherBot <= ballBot) && (otherBot >= ballTop + (ballHeight * 3/4))) {
			// -30 degree push
			xVel = VELOCITY * cos(toRadians(-30));
			yVel = VELOCITY * sin(toRadians(30));
		}
		else if ((otherTop >= ballBot - (ballHeight * 1/4)) && (otherTop <= ballBot)) {
			// 30 degree push
			xVel = VELOCITY * cos(toRadians(30));
			yVel = VELOCITY * sin(toRadians(-30));
		}
		else if ((otherTop >= ballBot - (ballHeight * 1/2)) && (otherTop <= ballBot - (ballHeight * 1/4))) {
			// 45 degree push
			xVel = VELOCITY * cos(toRadians(45));
			yVel = VELOCITY * sin(toRadians(-45));
		}
		else if ((otherTop >= ballBot - (ballHeight * 3/4)) && (otherTop <= ballBot - (ballHeight * 1/2))) {
			// 60 degree push
			xVel = VELOCITY * cos(toRadians(60));
			yVel = VELOCITY * sin(toRadians(-60));
		}
		else if ((otherTop >= ballBot - (ballHeight)) && (otherTop <= ballBot - (ballHeight * 3/4))) {
			// 30 degree push
			xVel = VELOCITY * cos(toRadians(30));
			yVel = VELOCITY * sin(toRadians(-30));
		}
		else if ((otherTop <= ballTop) && (otherBot >= ballBot)) {
			// Straight push
			xVel = VELOCITY;
			yVel = 0;
		}

	}

	else if ((otherLeft >= ballLeft + ballWidth/2) && (otherLeft <= ballRight)) {
		// Object is pushing from the right
		//std::cout << "Pushing from right" << std::endl;
		if ((otherBot <= ballTop + (ballHeight * 1/4)) && (otherBot >= ballTop)) {
			// -60 degree push
			xVel = VELOCITY * cos(toRadians(-60)) * -1;
			yVel = VELOCITY * sin(toRadians(60));
			//std::cout << "-60 degree push" << std::endl;
		}
		else if ((otherBot <= ballTop + (ballHeight * 1/2)) && (otherBot >= ballTop + (ballHeight * 1/4))) {
			// -45 degree push
			xVel = VELOCITY * cos(toRadians(-45)) * -1;
			yVel = VELOCITY * sin(toRadians(45));
			//std::cout << "-45 degree" << std::endl;
		}
		else if ((otherBot <= ballTop + (ballHeight * 3/4)) && (otherBot >= ballTop + (ballHeight * 1/2))) {
			// -30 degree push
			xVel = VELOCITY * cos(toRadians(-30)) * -1;
			yVel = VELOCITY * sin(toRadians(30));
			//std::cout << "-30 degree" << std::endl;
		}
		else if ((otherBot <= ballBot) && (otherBot >= ballTop + (ballHeight * 3/4))) {
			// -30 degree push
			xVel = VELOCITY * cos(toRadians(-30)) * -1;
			yVel = VELOCITY * sin(toRadians(30));
		}
		else if ((otherTop >= ballBot - (ballHeight * 1/4)) && (otherTop <= ballBot)) {
			// 30 degree push
			xVel = VELOCITY * cos(toRadians(30)) * -1;
			yVel = VELOCITY * sin(toRadians(-30));
			//std::cout << "30 degree" << std::endl;
		}
		else if ((otherTop >= ballBot - (ballHeight * 1/2)) && (otherTop <= ballBot - (ballHeight * 1/4))) {
			// 45 degree push
			xVel = VELOCITY * cos(toRadians(45)) * -1;
			yVel = VELOCITY * sin(toRadians(-45));
			//std::cout << "45 degree" << std::endl;
		}
		else if ((otherTop >= ballBot - (ballHeight * 3/4)) && (otherTop <= ballBot - (ballHeight * 1/2))) {
			// 60 degree push
			xVel = VELOCITY * cos(toRadians(60)) * -1;
			yVel = VELOCITY * sin(toRadians(-60));
			//std::cout << "60 degree" << std::endl;
		}
		else if ((otherTop >= ballBot - (ballHeight)) && (otherTop <= ballBot - (ballHeight * 3/4))) {
			// 30 degree push
			xVel = VELOCITY * cos(toRadians(30)) * -1;
			yVel = VELOCITY * sin(toRadians(-30));
		}
		else if ((otherTop <= ballTop) && (otherBot >= ballBot)) {
			// Straight push
			xVel = VELOCITY * -1;
			yVel = 0;
		}
	}


	/* Bottom edge			 			Ball center					Bottom edge			 Ball Top edge */
	else if ((otherBot <= ballTop + ballHeight/2) && (otherBot >= ballTop)) {
		// Object is pushing from the top
		if (otherLeft >= ballLeft && otherLeft <= ballLeft + (ballWidth * 1/4)) {
			//
			xVel = VELOCITY * cos(toRadians(-60)) * -1;
			yVel = VELOCITY * sin(toRadians(60));
		}
		else if (otherLeft >= ballLeft + (ballWidth * 1/4) && otherLeft <= ballLeft + (ballWidth * 1/2)) {
			xVel = VELOCITY * cos(toRadians(-60)) * -1;
			yVel = VELOCITY * sin(toRadians(60));
		}
		else if (otherLeft >= ballLeft + (ballWidth * 1/2) && otherLeft <= ballLeft + (ballWidth * 3/4)) {
			xVel = VELOCITY * cos(toRadians(-45)) * -1;
			yVel = VELOCITY * cos(toRadians(45));
		}
		else if (otherLeft >= ballLeft + (ballWidth * 3/4) && otherLeft <= ballLeft + ballWidth) {
			xVel = VELOCITY * cos(toRadians(-30)) * -1;
			yVel = VELOCITY * sin(toRadians(30));
		}
		else if (otherRight >= ballLeft && otherRight <= ballLeft + (ballWidth * 1/4)) {
			xVel = VELOCITY * cos(toRadians(30));
			yVel = VELOCITY * sin(toRadians(30));
		}
		else if (otherRight >= ballLeft + (ballWidth * 1/4) && otherRight <= ballLeft + (ballWidth * 1/2)) {
			xVel = VELOCITY * cos(toRadians(45));
			yVel = VELOCITY * sin(toRadians(45));
		}
		else if (otherRight >= ballLeft + (ballWidth * 1/2) && otherRight <= ballLeft + (ballWidth * 3/4)) {
			xVel = VELOCITY * cos(toRadians(60));
			yVel = VELOCITY * sin (toRadians(60));
		}
		else if (otherRight >= ballLeft + (ballWidth * 3/4) && otherRight <= ballLeft + ballWidth) {
			xVel = VELOCITY * cos(toRadians(60));
			yVel = VELOCITY * sin(toRadians(60));
		}
		else if (otherRight >= ballRight && otherLeft <= ballLeft) {
			xVel = 0;
			yVel = VELOCITY;
		}
		else {
			xVel = 0;
			yVel = 0;
		}
	}



	/*	 Top edge			 	Ball center					Top edge			Ball Bottom edge */
	else if ((otherTop >= ballBot - ballHeight/2) && (otherTop <= ballBot)) {

		// Object is pushing from the top
		if (otherLeft >= ballLeft && otherLeft <= ballLeft + (ballWidth * 1/4)) {
			//
			xVel = VELOCITY * cos(toRadians(-60)) * -1;
			yVel = VELOCITY * sin(toRadians(-60));
		}
		else if (otherLeft >= ballLeft + (ballWidth * 1/4) && otherLeft <= ballLeft + (ballWidth * 1/2)) {
			xVel = VELOCITY * cos(toRadians(-60)) * -1;
			yVel = VELOCITY * sin(toRadians(-60));
		}
		else if (otherLeft >= ballLeft + (ballWidth * 1/2) && otherLeft <= ballLeft + (ballWidth * 3/4)) {
			xVel = VELOCITY * cos(toRadians(-45)) * -1;
			yVel = VELOCITY * cos(toRadians(-45));
		}
		else if (otherLeft >= ballLeft + (ballWidth * 3/4) && otherLeft <= ballLeft + ballWidth) {
			xVel = VELOCITY * cos(toRadians(-30)) * -1;
			yVel = VELOCITY * sin(toRadians(-30));
		}
		else if (otherRight >= ballLeft && otherRight <= ballLeft + (ballWidth * 1/4)) {
			xVel = VELOCITY * cos(toRadians(30));
			yVel = VELOCITY * sin(toRadians(-30));
		}
		else if (otherRight >= ballLeft + (ballWidth * 1/4) && otherRight <= ballLeft + (ballWidth * 1/2)) {
			xVel = VELOCITY * cos(toRadians(45));
			yVel = VELOCITY * sin(toRadians(-45));
		}
		else if (otherRight >= ballLeft + (ballWidth * 1/2) && otherRight <= ballLeft + (ballWidth * 3/4)) {
			xVel = VELOCITY * cos(toRadians(60));
			yVel = VELOCITY * sin (toRadians(-60));
		}
		else if (otherRight >= ballLeft + (ballWidth * 3/4) && otherRight <= ballLeft + ballWidth) {
			xVel = VELOCITY * cos(toRadians(60));
			yVel = VELOCITY * sin(toRadians(-60));
		}
		else if (otherRight >= ballRight && otherLeft <= ballLeft) {
			xVel = 0;
			yVel = VELOCITY * -1;
		}
		else {
			xVel = 0;
			yVel = 0;
		}
	}
	else {
		xVel = 0;
		yVel = 0;
	}
}

void StationaryBall::move() {
	position.x += (xVel * 1.25);
	if (position.x < 0) {
		position.x = 0;
	}
	else if (position.x > SCREEN_WIDTH - position.w) {
		position.x = SCREEN_WIDTH - position.w;
	}

	position.y += (yVel * 1.25);
	if (position.y < 0) {
		position.y = 0;
	}
	else if (position.y > SCREEN_HEIGHT - position.h) {
		position.y = SCREEN_HEIGHT - position.h;
	}
}

int Ball::getLocation() {
	int result = FIELD_POSITION_15;

	SDL_Rect center = this->getCenter();
	if (center.x <= 280 && center.x >= 70) {
		// In the first "row"
		if (center.y >= 70 && center.y <= 220) {
			result = FIELD_POSITION_1;
		}
		else if (center.y >= 220 && center.y <= 520) {
			result = FIELD_POSITION_5;
		}
		else if (center.y >= 520 && center.y <= 670) {
			result = FIELD_POSITION_9;
		}
	}
	else if (center.x >= 280 && center.x <= 520) {
		// In the second "row"
		if (center.y >= 70 && center.y <= 220) {
			result = FIELD_POSITION_2;
		}
		else if (center.y >= 220 && center.y <= 520) {
			result = FIELD_POSITION_6;
		}
		else if (center.y >= 520 && center.y <= 670) {
			result = FIELD_POSITION_10;
		}
	}
	else if (center.x >= 520 && center.y <= 760) {
		// In the third "row"
		if (center.y >= 70 && center.y <= 220) {
			result = FIELD_POSITION_3;
		}
		else if (center.y >= 220 && center.y <= 520) {
			result = FIELD_POSITION_7;
		}
		else if (center.y >= 520 && center.y <= 670) {
			result = FIELD_POSITION_11;
		}
	}
	else if (center.x >= 760 && center.x <= 970) {
		// In the fourth "row"
		if (center.y >= 70 && center.y <= 220) {
			result = FIELD_POSITION_4;
		}
		else if (center.y >= 220 && center.y <= 520) {
			result = FIELD_POSITION_8;
		}
		else if (center.y >= 520 && center.y <= 670) {
			result = FIELD_POSITION_12;
		}
	}
	else if (center.y <= 520 && center.y >= 220) {
		if (center.x <= 70 && center.x >= 10) {
			result = FIELD_POSITION_13;
		}
		else if (center.x <= 1030 && center.x >= 970){
			result = FIELD_POSITION_14;
		}
	}

	return result;
}
